/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef LIB2D_OBJECTS_SEQUENCE_H
#define LIB2D_OBJECTS_SEQUENCE_H

#include <xml/Object.h>
#include <SharedRep.h>
#include <math/utl.h>
#include <Atom.h>
#include <filesystem/String.hpp>
#include "ImageSequence.h"

namespace liba
{
namespace lib2d
{
namespace objects
{

class Sequence :
	public xml::ObjectANSI,
	public SharedPrecached< ImageSequence::Param, ImageSequence >
{
public:
	enum LoopType { NONE, FORWARD, PING_PONG };
	enum AlignX { AX_CENTER, AX_LEFT, AX_RIGHT };
	enum AlignY { AY_CENTER, AY_TOP, AY_BOTTOM };

	Sequence();

	virtual bool on_attribute( xml::Provider * prov, const std::string & name, const std::string & value );
	virtual bool on_end_node( xml::Provider * prov );

	void render_frame( hard::Renderer * rend, const Vector2 & dst, unsigned frame, int alpha )
	{
		if( frame > frame_end - frame_start )
			return;

		hard::Image * img = get_rep()->get_image( rend, frame_start + frame );
		if( !img )
			return;
		if( !img->is_valid() )
		{
			get_rep()->start_loading();
			return;
		}

		img->blit( dst, alpha );
	}
	const Atom & get_name()const
	{
		return name;
	}
	int get_frames_count()const
	{
		return frame_end - frame_start+1;
	}
	int get_height()const
	{
		return frame_height;
	}
	int get_width()const
	{
		return frame_width;
	}
	LoopType get_loop_type()const
	{
		return loop_type;
	}
	float get_frame_duration()const
	{
		return frame_duration;
	}
	AlignX get_align_x()const
	{
		return align_x;
	}
	AlignY get_align_y()const
	{
		return align_y;
	}

	static converter::EnumPair<char,LoopType> LoopTypeNames[];
	static converter::EnumPair<char,AlignX> AlignXNames[];
	static converter::EnumPair<char,AlignY> AlignYNames[];

private:
	Atom name;
	filesystem::String image_name;
	LoopType loop_type;
	float frame_duration;
	AlignX align_x;
	AlignY align_y;
	int frame_height;
	int frame_width;
	int frame_start;
	int frame_end;
};

} //namespace objects
} //namespace lib2d

namespace converter
{
template<>
struct ConverterTraits<char, lib2d::objects::Sequence::LoopType>
	:	public ConverterTraitsEnumBase<char, lib2d::objects::Sequence::LoopType, lib2d::objects::Sequence::LoopTypeNames>
{};

template<>
struct ConverterTraits<char, lib2d::objects::Sequence::AlignX>
	:	public ConverterTraitsEnumBase<char, lib2d::objects::Sequence::AlignX, lib2d::objects::Sequence::AlignXNames>
{};

template<>
struct ConverterTraits<char, lib2d::objects::Sequence::AlignY>
	:	public ConverterTraitsEnumBase<char, lib2d::objects::Sequence::AlignY, lib2d::objects::Sequence::AlignYNames>
{};
} //namespace converter
} //namespace liba
using namespace liba;

#endif //LIB2D_OBJECTS_SEQUENCE_H